home *** CD-ROM | disk | FTP | other *** search
/ Aminet 49 / Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso / Aminet / comm / news / slrn-BIN.lha / slrn-BIN-0.9.7.4 / contrib / cleanscore next >
Text File  |  2001-11-03  |  10KB  |  371 lines

  1. #!/usr/bin/perl -w
  2. # cleanscore - Remove expired entrys from slrn's Scorefile.
  3.  
  4. # Copyright (c) 1999 - 2001 Felix Schueller <fschueller@netcologne.de>
  5. # This program is free software; you can redistribute it and/or modify it
  6. # under the terms of the GNU General Public License as published by the Free
  7. # Software Foundation; either version 2 of the License, or (at your option)
  8. # any later version.
  9. #     
  10. # This program is distributed in the hope that it will be useful, but WITHOUT
  11. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13. # more details.
  14. #
  15. # You should have received a copy of the GNU General Public License along
  16. # with this program; if not, write to the Free Software Foundation, Inc.,
  17. # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   
  18.  
  19. use Fcntl qw(:DEFAULT :flock);
  20.  
  21. sub help();
  22. sub reset_vars();
  23. sub insert_comment();
  24. sub end_of_score();
  25. sub clean_file($);
  26.  
  27. $version="0.9.8.0";
  28. $DEBUG = 0;
  29. $remove_comments = 0;
  30. $max_empty_lines = -1;
  31. $VERBOSE = 0;
  32. $keep = 0;
  33. $test_only = 0;
  34. $save_file = "";
  35. $bak_ext = ".bak";
  36. $ign_pat = "";
  37.  
  38. require "getopts.pl"; &Getopts('b:de:f:hi:k:hrs:tVv');
  39. if (defined($opt_b)) {$bak_ext = $opt_b;}
  40. if (defined($opt_d)) {$DEBUG = $opt_d;}
  41. if (defined($opt_e)) {$max_empty_lines = $opt_e;}
  42. if (defined($opt_h)) {help(); exit(0);}
  43. if (defined($opt_i)) {$ign_pat = $opt_i;}
  44. if (defined($opt_r)) {$remove_comments = $opt_r;}
  45. if (defined($opt_s)) {$save_file = $opt_s;}
  46. if (defined($opt_t)) {$test_only = $opt_t;}
  47. if (defined($opt_k)) {$keep = $opt_k * 86400;}
  48. if (defined($opt_v)) {$VERBOSE = $opt_v;}
  49. if (defined($opt_V)) {print ("cleanscore - Version: $version (bugreports to: fschueller\@netcologne.de)\n"); exit(0);}
  50. $opt_h = $opt_V; # suppress 'perl -w' warnings.
  51.  
  52. if (defined($opt_f))
  53.   {
  54.     ($target = $opt_f) =~ s#/$##g;
  55.   }
  56. else
  57.   {
  58.     print("You must specify a scorefile with the '-f scorefile' option.\n");
  59.     print("Try 'cleanscore -h' for a more detailed help\n");
  60.     exit 1;
  61.   }
  62.   
  63. if ($DEBUG)
  64.   {
  65.     print ("Version: $version\n");
  66.     if (defined($opt_k)) {print ("Keep: $keep ($opt_k)\n");}
  67.     print ("\n");
  68.   }
  69.  
  70. if (-f $target)
  71.   {
  72.     clean_file($target);
  73.   }
  74. elsif (-d $target)
  75.   {
  76.     my $bak_pat=$bak_ext;
  77.     opendir(SCOREDIR, $target) || die ("Can't open $target: $!");
  78.     # escape characters with special meaning.
  79.     $bak_pat=~ s/\./\\./g;
  80.     foreach (readdir(SCOREDIR))
  81.       {
  82.         if (/^\.\.?$/) {next;} # skip '.' and '..' 
  83.     if (/$bak_pat$/o) {next;} # skip $bak_ext
  84.     if ($ign_pat) { if (/$ign_pat$/o) {next;} };
  85.     unless ( -f "$target/$_") {next;} # skip everything that is not a normal file.
  86.     clean_file("$target/$_");
  87.       }
  88.   }
  89.  
  90. ############################ END OF MAIN ###############################
  91.  
  92. sub clean_file($)
  93. {
  94.   my $score_file = shift;
  95.   my (@ak_date, $ak_year, $ak_month, $ak_day);
  96.   my ($day, $month, $year);
  97.   my $prev_empty_lines=0, $group= -1;
  98.  
  99.   
  100.   if ($DEBUG)
  101.   {
  102.     print ("\nScorefile: $score_file\n");
  103.     print ("Dates: Entry / System");
  104.     if ($keep) {print (" - $opt_k Days");}
  105.     print ("\n\n");
  106.   }
  107.  
  108.   @ak_date = localtime (time - $keep);
  109.   $ak_year = ($ak_date[5] + 1900);
  110.   $ak_month = ($ak_date[4] + 1);
  111.   $ak_day = $ak_date[3];
  112.  
  113.   unless ($test_only)
  114.     {  
  115.       sysopen (SCORE, "$score_file", O_RDWR) || die ("Can't open $score_file: $!");
  116.       flock (SCORE, LOCK_EX | LOCK_NB) || die ("Can't lock $score_file: $!");
  117.       sysopen (OUT, "$score_file.cs", O_RDWR | O_CREAT) || die ("Can't open $score_file.cs: $!");
  118.       $file_is_changed=0;
  119.     }
  120.   else
  121.     {
  122.       open (SCORE, "$score_file") || die ("Can't read $score_file: $!");
  123.     }
  124.  
  125.   reset_vars();
  126.   @$comment = "";
  127.   $co_line = 0;
  128.  
  129.   #Magic starts here
  130.   while (<SCORE>)
  131.     {
  132.       # Removing empty lines is a problem, we don't know to whitch entrie they belong.
  133.       # So we provide the an option to cut multiple empty lines down to $max_empty_lines 
  134.       if ($max_empty_lines >= 0) 
  135.         {
  136.           if (/^\s*$/)
  137.             {
  138.           if ($prev_empty_lines==$max_empty_lines)
  139.             {
  140.               $file_is_changed=1;
  141.           next;
  142.             }
  143.           else
  144.             {
  145.               $prev_empty_lines++;
  146.             }
  147.         }
  148.           else
  149.             {
  150.           if ($prev_empty_lines)
  151.             {
  152.               $prev_empty_lines=0;
  153.             }
  154.         }
  155.         }
  156.     
  157.       if ($remove_comments) # Remove '%' comments
  158.         {
  159.           if (/^\s*%/)
  160.             {
  161.               if ($VERBOSE || $DEBUG) {print ($_);}
  162.               $file_is_changed=1;
  163.           next;
  164.             }
  165.         }
  166.   
  167.       if (/\%EOS/ || /#EOS/)
  168.         {
  169.           $comment[$co_line] = $_;
  170.           $co_line++;
  171.           insert_comment();        
  172.           end_of_score();
  173.           next;
  174.         }
  175.   
  176.       if (/\%BOS/ || /#BOS/)
  177.         {
  178.           insert_comment();
  179.           end_of_score();
  180.           $seen_bos = 1;
  181.         }
  182.   
  183.       if (/^\s*%/ || /^\s*#/ || /^\s*$/)  # put comments in an extra array
  184.         {
  185.           $comment[$co_line] = $_;
  186.           $co_line++;
  187.           next;
  188.         }
  189.  
  190.       if (/Expires:/i)
  191.         {
  192.           if (/\d{1,2}-\d{1,2}-\d{4}/)
  193.             {
  194.               ($day, $month, $year) = /(\d{1,2})-(\d{1,2})-(\d{4})/;
  195.             }
  196.           else
  197.             {
  198.               ($month, $day, $year) = m#(\d{1,2})/(\d{1,2})/(\d{4})#;
  199.             }
  200.           if ($DEBUG)
  201.             {
  202.               print ("Year: $year / $ak_year\n");
  203.               print ("Month: $month / $ak_month\n");
  204.               print ("Day: $day / $ak_day\n");
  205.             }
  206.           if ($year < $ak_year)
  207.             {
  208.               $is_expired = 1;
  209.             }
  210.           elsif ($year == $ak_year)
  211.             {
  212.               if ($month < $ak_month)
  213.             {
  214.                   $is_expired = 1;
  215.                 }
  216.             elsif ($month == $ak_month)
  217.               {
  218.                   if ($day <= $ak_day) {$is_expired = 1;}
  219.                 }
  220.             }
  221.           if ($DEBUG && $is_expired) {print ("Entry is expired\n");}
  222.         }
  223.  
  224.       if (/^\S*\[.*\]\S*$/)  # Found a new groupexpression - entry ends here
  225.         {
  226.           #unless ($seen_bos)
  227.             #{
  228.       end_of_score();
  229.           insert_comment();
  230.         #}
  231.           $group=$sc_line;
  232.         }
  233.   
  234.       if (/Score:/i)
  235.         {
  236.           if ($seen_score) #there was a 'Score:' before entry ends here
  237.             {
  238.               if ($is_expired && $group >= 0) # Save Groupexp if necessary
  239.                 {
  240.               unless ($test_only) {print (OUT $ak_score[$group]);}
  241.                 }
  242.               end_of_score();
  243.               insert_comment();
  244.               $group = -1;
  245.             }
  246.           $seen_score = 1;
  247.         }
  248.       insert_comment();
  249.       $ak_score[$sc_line] = $_;
  250.       $sc_line++;
  251.     } #while (<SCORE>)
  252.  
  253.   end_of_score();
  254.   insert_comment();
  255.   end_of_score();
  256.  
  257.   unless ($test_only)
  258.     {
  259.       if ($file_is_changed)
  260.         {
  261.           # $score_file.cs contains the new scorefile $score_file the old.
  262.           
  263.       # copy $score_file to $score_file$bak_ext
  264.           seek (SCORE, 0, 0) || die ("Can't rewind $score_file: $!");
  265.           open (DEST, ">$score_file$bak_ext") || die ("Can't write $score_file$bak_ext: $!");
  266.           while (<SCORE>) {print (DEST $_);}
  267.           close (DEST);
  268.           
  269.       # copy $score_file.cs to $score_file
  270.           seek (SCORE, 0, 0) || die ("Can't rewind $score_file: $!");
  271.           truncate (SCORE, 0);
  272.           seek (OUT, 0, 0) || die ("Can't rewind $score_file.cs: $!");
  273.           while (<OUT>) {print (SCORE $_);}
  274.         }
  275.       close (OUT);
  276.       if (-e "$score_file.cs") { unlink("$score_file.cs")};
  277.     }
  278.   close (SCORE);
  279. } #sub clean_file($)
  280.  
  281. sub end_of_score()
  282. {
  283.   unless ($is_expired || $test_only)
  284.     {
  285.       print (OUT @ak_score);
  286.     }
  287.   else
  288.     {
  289.       $file_is_changed=1;
  290.       if ($save_file && $is_expired)
  291.         {
  292.       open (SAVE, ">>$save_file") || die ("Can't append to $save_file: $!");
  293.       print (SAVE @ak_score);
  294.       close (SAVE);
  295.     }
  296.       if ($VERBOSE || $DEBUG)
  297.         {
  298.           print (@ak_score);
  299.           print ("\nNext Entry:\n\n");
  300.         }
  301.     }
  302.   reset_vars();
  303. } #sub end_of_score()
  304.  
  305. sub insert_comment()
  306. {
  307.   if ($co_line)
  308.     {
  309.       for ($i=0; $i < $co_line; $i++)
  310.         {
  311.           $ak_score[$sc_line] = $comment[$i];
  312.           $sc_line++;
  313.         }
  314.     }
  315.   $co_line = 0;
  316.   @comment = "";
  317. }
  318.  
  319. sub reset_vars()
  320. {
  321.   @ak_score ="";
  322.   $is_expired = 0;
  323.   $seen_bos = 0;
  324.   $seen_score = 0;
  325.   $sc_line = 0;
  326. }
  327.  
  328. sub help()
  329. {
  330.   print <<EOF;
  331. cleanscore - Remove expired entries from slrn's Scorefile.
  332.  
  333.    -V              "Version."  Print Version and exit.
  334.    -h              "Help".     Prints a help message.
  335.  
  336.  
  337.    -b <extension>  "Backup extention".   Overwrites the default backup-
  338.                    extention ('.bak')
  339.            
  340.    -d              "Debug."    Prints dates and status for each entry.
  341.  
  342.    -e n            "Empty lines." Cut multiple empty lines down to N.
  343.    
  344.    -f <filename>   "File".   Chose "filename" for cleaning.   **Required**
  345.                              If "filename" is a directory
  346.                  clean all files in it.
  347.  
  348.    -i <pattern>    "Ignore pattern".   When scanning through a directory
  349.                    ignore files with names matching "pattern".
  350.            The "backup extention" is matcht automaticly.
  351.            
  352.    -k n            "Keep for N days".
  353.                    Do not remove expired entries, but instead hold them
  354.                    for N more days.  This allows to keep expired entries
  355.                    so you can still edit them, eg. change the expiry date.
  356.  
  357.    -r              "Remove".  Removes comment lines, i.e. lines beginning
  358.                    with '%'. (e.g. remove slrn generated comments
  359.                    when you use '#' for your own comments).
  360.  
  361.    -s <filename>   "Save to". Save removed entries to "filename".
  362.  
  363.    -t              "Test".  Just check for expired entries
  364.                    but do not change the scorefile.
  365.                    Make sense with options -v or -d only.
  366.  
  367.    -v              "Verbose".  Prints all expired entries to stdout.
  368. EOF
  369. }
  370.